#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QtDebug>
#include <QFile>
#include "cipher.h"
#include "binarytextedit.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_encrypt_clicked()
{
    Cipher cipher;
    Cipher::CipherAlgorithm algorithm;
    if (ui->binaryMode->isChecked())
        cipher.setBinaryMode();
    else
        cipher.setAsciiMode();

    if (ui->cipher_caesar->isChecked())
//        algorithm = Cipher::Caesar;
//    else if (ui->cipher_vigenere->isChecked())
        algorithm = ui->xorMode->isChecked() ? Cipher::XORVigenere : Cipher::Vigenere;
    else // ui->cipher_autokey->isChecked()
        algorithm = ui->xorMode->isChecked() ? Cipher::XORAutokey  : Cipher::Autokey;

    QByteArray key = ui->key->binaryData();
    if (!ui->binaryMode->isChecked()) key = key.toUpper();

    cipher.setPlainText(ui->binaryMode->isChecked() ? ui->plainText->binaryData()
                                                    : ui->plainText->binaryData().toUpper());
    cipher.encrypt(key, algorithm); //TODO thread this
    ui->cipherText->setBinaryData(cipher.cipherText());
}

void MainWindow::on_cEscape_clicked()
{
    ui->plainText->setEscapeMode(BinaryTextEdit::CEscape);
    ui->cipherText->setEscapeMode(BinaryTextEdit::CEscape);
    ui->key->setEscapeMode(BinaryTextEdit::CEscape);
}

void MainWindow::on_URLEscape_clicked()
{
    ui->plainText->setEscapeMode(BinaryTextEdit::URLEscape);
    ui->cipherText->setEscapeMode(BinaryTextEdit::URLEscape);
    ui->key->setEscapeMode(BinaryTextEdit::URLEscape);
}

void MainWindow::on_hex_clicked()
{
    ui->plainText->setEscapeMode(BinaryTextEdit::Hex);
    ui->cipherText->setEscapeMode(BinaryTextEdit::Hex);
    ui->key->setEscapeMode(BinaryTextEdit::Hex);
}

void MainWindow::on_base64_clicked()
{
    ui->plainText->setEscapeMode(BinaryTextEdit::Base64);
    ui->cipherText->setEscapeMode(BinaryTextEdit::Base64);
    ui->key->setEscapeMode(BinaryTextEdit::Base64);
}

void MainWindow::on_decrypt_clicked()
{
//    qDebug() << "decrypt";
    Cipher cipher;
    Cipher::CipherAlgorithm algorithm;
    if (ui->binaryMode->isChecked())
        cipher.setBinaryMode();
    else
        cipher.setAsciiMode();

    if (ui->cipher_caesar->isChecked())
//        algorithm = Cipher::Caesar;
//    else if (ui->cipher_vigenere->isChecked())
        algorithm = ui->xorMode->isChecked() ? Cipher::XORVigenere : Cipher::Vigenere;
    else // ui->cipher_autokey->isChecked()
        algorithm = ui->xorMode->isChecked() ? Cipher::XORAutokey  : Cipher::Autokey;


    QByteArray key = ui->key->binaryData();
    if (!ui->binaryMode->isChecked()) key = key.toUpper();

    cipher.setCipherText(ui->binaryMode->isChecked() ? ui->cipherText->binaryData()
                                                     : ui->cipherText->binaryData().toUpper());
    cipher.decrypt(key, algorithm); //TODO thread this
    ui->plainText->setBinaryData(ui->binaryMode->isChecked() ? cipher.plainText()
                                                             : cipher.plainText().toLower());
}

void MainWindow::on_decryptt_clicked()
{
    on_decrypt_clicked();
}

void MainWindow::on_binaryMode_clicked(bool checked)
{
    if (checked)
    {
        if (ui->cEscape->isChecked())
            on_cEscape_clicked();
        else if (ui->URLEscape->isChecked())
            on_URLEscape_clicked();
        else if (ui->hex->isChecked())
            on_hex_clicked();
        else // ui->base64->isChecked()
            on_base64_clicked();
    }
    else
    {
        ui->plainText->setEscapeMode(BinaryTextEdit::None);
        ui->cipherText->setEscapeMode(BinaryTextEdit::None);
        ui->key->setEscapeMode(BinaryTextEdit::None);
    }
}

void MainWindow::on_loadPlainText_clicked()
{
    load(ui->plainText);
}

void MainWindow::on_loadCipherText_clicked()
{
    load(ui->cipherText);
}

void MainWindow::on_savePlainText_clicked()
{
    save(ui->plainText);
}

void MainWindow::on_saveCipherText_clicked()
{
    save(ui->cipherText);
}

void MainWindow::load(BinaryTextEdit *destination)
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"));
    QFile inputFile(fileName);
    inputFile.open(QIODevice::ReadOnly);

    destination->setBinaryData(inputFile.readAll());
}

void MainWindow::save(BinaryTextEdit *source)
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("Open File"));
    QFile outputFile(fileName);
    outputFile.open(QIODevice::WriteOnly);
    outputFile.write(source->binaryData());
}
